<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">
<html>
<title>Bloomberg Development Environment</title>
<html>
<pre>
// Copyright 2016-2023 Bloomberg Finance L.P.
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// bmqa_confirmeventbuilder.h                                         -*-C++-*-
#ifndef INCLUDED_BMQA_CONFIRMEVENTBUILDER
#define INCLUDED_BMQA_CONFIRMEVENTBUILDER

//@PURPOSE: Provide a builder for batching confirmation messages.
//
//@CLASSES:
//  bmqa::ConfirmEventBuilder: builder for batching confirmation messages.
//
//@DESCRIPTION: This component implements a mechanism,
// &#39;bmqa::ConfirmEventBuilder&#39;, that can be used for batching CONFIRM messages.
// The resulting batch can be sent to the BlazingMQ broker using the
// &#39;bmqa::Session&#39; (refer to &#39;bmqa_session&#39; for details).  Wherever possible, a
// BlazingMQ consumer should try to send a batch of CONFIRM messages, which is
// more efficient than confirming messages individually.
//
// The builder holds a batch of CONFIRM messages under construction, and
// provides two flavors of &#39;addMessageConfirmation&#39; method to add a CONFIRM
// message to the batch.  It also provides a routine to retrieve number of
// CONFIRM messages added to the batch.  Once application is done creating the
// batch, it can retrieve the blob (wire-representation) of the batch and send
// it via &#39;bmqa::Session&#39;.  See &#39;Usage&#39; section for more details.
//
///Usage
///-----
//: o An instance of bmqa::ConfirmEventBuilder (the builder) can be used to
//:   create multiple batches of CONFIRM messages.  The recommended approach is
//:   to create one instance of the builder and use it throughout the lifetime
//:   of the task (if the task is multi-threaded, an instance per thread must
//:   be created and maintained).  See usage example #1 for an illustration.
//:
//: o The lifetime of an instance of the builder is bound by the bmqa::Session
//:   from which it was created.  In other words, bmqa::Session instance must
//:   outlive the builder instance.
//
///Example 1 - Basic Usage
///-----------------------
//..
//   // In this snippet, we will send a batch of CONFIRMs for all the
//   // &#39;bmqa::Message&#39; messages received in a &#39;bmqa::MessageEvent&#39;.
//
//   // Note that error handling is omitted from the snippet for the sake of
//   // brevity.
//
//   bmqa::Session session;
//       // Session start up logic elided.
//
//   // Create and load an instance of the ConfirmEventBuilder.  Note that in
//   // this example, we are creating the builder on the stack everytime a
//   // message event is received.  Another approach can be to maintain the
//   // builder as a data member and use it everytime.
//
//   bmqa::ConfirmEventBuilder builder;
//   session.loadConfirmEventBuilder(&amp;builder);
//
//   // Assuming that a &#39;bmqa::MessageEvent&#39; is received.
//
//   bmqa::MessageIterator iter = messageEvent.messageIterator();
//   while (iter.nextMessage()) {
//       const bmqa::Message&amp; msg = iter.message();
//
//       // Business logic for processing &#39;msg&#39; elided.
//
//       int rc = builder.addMessageConfirmation(msg);
//           // Error handling elided.
//   }
//
//   // All messages in the event have been processed and their corresponding
//   // CONFIRM messages have been batched.  Now its time to send the batch to
//   // the BlazingMQ broker.
//
//   int rc = session.confirmMessages(&amp;builder);
//       // Error handling elided.  Note that in case of success, above method
//       // will also reset the &#39;builder&#39;.
//..
//
///Thread Safety
///-------------
// This component is *NOT* thread safe.  If it is desired to create a batch of
// CONFIRM messages from multiple threads, an instance of the builder must be
// created and maintained *per* *thread*.


// BMQ
#include &lt;bmqscm_version.h&gt;
#include &lt;bmqa_message.h&gt;
#include &lt;bmqt_resultcode.h&gt;

// BDE
#include &lt;bdlbb_blob.h&gt;
#include &lt;bsls_alignedbuffer.h&gt;

namespace BloombergLP {

// FORWARD DECLARATION
namespace bmqp { class ConfirmEventBuilder; }

namespace bmqa {

                       // ==============================
                       // struct ConfirmEventBuilderImpl
                       // ==============================

struct ConfirmEventBuilderImpl {
    // Component-private class.  Do not use.

    // CONSTANTS
    static const int k_MAX_SIZEOF_BMQP_CONFIRMEVENTBUILDER = 64;
        // Constant representing the maximum size of a
        // &#39;bmqp::ConfirmEventBuilder&#39; object, so that the below AlignedBuffer
        // is big enough.  Note that since this buffer will hold a
        // &#39;bmqp::ConfirmEventBuilder&#39; which holds a &#39;bdlbb::Blob&#39; data member,
        // the size is different on 32 vs 64 bits.

    // PUBLIC DATA
    //   (for convenience)
    bsls::AlignedBuffer&lt;k_MAX_SIZEOF_BMQP_CONFIRMEVENTBUILDER&gt;  d_buffer;

    bmqp::ConfirmEventBuilder                                  *d_builder_p;

    // CREATORS
    ConfirmEventBuilderImpl();

  private:
    // NOT IMPLEMENTED
    ConfirmEventBuilderImpl(const ConfirmEventBuilderImpl&amp;); // = delete
    ConfirmEventBuilderImpl&amp;
    operator=(const ConfirmEventBuilderImpl&amp;);               // = delete
};


                         // =========================
                         // class ConfirmEventBuilder
                         // =========================

class ConfirmEventBuilder {
    // Mechanism to build a batch of CONFIRM messages.

  private:
    // DATA
    ConfirmEventBuilderImpl d_impl;

  private:
    // NOT IMPLEMENTED
    ConfirmEventBuilder(const ConfirmEventBuilder&amp; other); // = delete
    ConfirmEventBuilder&amp;
    operator=(const ConfirmEventBuilder&amp; rhs);             // = delete
        // Copy constructor and assignment operator not implemented

  public:
    // CREATORS
    ConfirmEventBuilder();
        // Create an invalid instance.  Application should not create
        // &#39;ConfirmEventBuilder&#39; themselves, but ask the &#39;bmqa::Session&#39; to
        // give them one, by using &#39;bmqa::Session::loadConfirmEventBuilder&#39;.

    ~ConfirmEventBuilder();
        // Destroy this instance.

    // MANIPULATORS
    bmqt::EventBuilderResult::Enum
    addMessageConfirmation(const Message&amp; message);
        // Append a confirmation message for the specified &#39;message&#39;.  Return
        // zero on success, and a non-zero value otherwise.  Behavior is
        // undefined unless this instance was obtained using
        // &#39;bmqa::Session::loadConfirmEventBuilder&#39;.

    bmqt::EventBuilderResult::Enum
    addMessageConfirmation(const MessageConfirmationCookie&amp; cookie);
        // Append a confirmation message for the specified
        // MessageConfirmationCookie &#39;cookie&#39;.  Return zero on success, and a
        // non-zero value otherwise.  Behavior is undefined unless this
        // instance was obtained using
        // &#39;bmqa::Session::loadConfirmEventBuilder&#39;.

    void reset();
        // Reset the builder, effectively discarding the batch of confirmation
        // messages under construction.

    // ACCESSORS
    int messageCount() const;
        // Return the number of messages currently in the ConfirmEvent being
        // built.  Behavior is undefined unless this instance was obtained
        // using &#39;bmqa::Session::loadConfirmEventBuilder&#39;.

    const bdlbb::Blob&amp; blob() const;
        // Return a reference not offering modifiable access to the blob of
        // confirmation messages batch built by this builder.  If no messages
        // were added, this will return an empty blob, i.e., a blob with
        // &#39;length == 0&#39;.  Behavior is undefined unless this instance was
        // obtained using &#39;bmqa::Session::loadConfirmEventBuilder&#39;.
};


// ============================================================================
//                             INLINE DEFINITIONS
// ============================================================================

                       // ------------------------------
                       // struct ConfirmEventBuilderImpl
                       // ------------------------------

// CREATORS
inline
ConfirmEventBuilderImpl::ConfirmEventBuilderImpl()
: d_buffer()
, d_builder_p(0)
{
    // NOTHING
}


                         // -------------------------
                         // class ConfirmEventBuilder
                         // -------------------------

// CREATORS
inline
ConfirmEventBuilder::ConfirmEventBuilder()
: d_impl()
{
    // NOTHING
}

// MANIPULATORS
inline
bmqt::EventBuilderResult::Enum
ConfirmEventBuilder::addMessageConfirmation(const Message&amp; message)
{
    return addMessageConfirmation(message.confirmationCookie());
}

}  // close package namespace
}  // close enterprise namespace

#endif
</pre>
</body>
</html>
